Imports System.io
Namespace Threads
    Friend Class TH_firmware
        Inherits BikiSoft.Threads.BikiThread

        Const rst As Byte = 16
        Private m_data() As Byte = Nothing
        Private m_UsbCommHandler As Comm.UsbCommunicationHandle = Nothing

        Sub New(ByVal Handler As Comm.UsbCommunicationHandle)
            m_UsbCommHandler = Handler
        End Sub

        Friend Overloads Sub Execute( _
                 ByVal backGroundWorker As System.ComponentModel.BackgroundWorker, _
                 ByVal e As System.ComponentModel.DoWorkEventArgs)
            ' -------------------- Calls the inherited execute routine
            MyBase.Execute(backGroundWorker, e)
            Dim f_ret As BK_return
            Dim nId As UInt32 = 0
            OnMessage("Firmware Update Initialised")
            m_UsbCommHandler.Close()

start:      If m_UsbCommHandler.Open(Comm.UsbCommunicationHandle.UsbMode.Bootloader) Then
                m_UsbCommHandler.ResetForBootMode()

                f_ret = MyClass.BikiRom_BootloaderUpload(nId)

                If f_ret <> BK_return.BK_OK And _
                  (f_ret = BK_return.BK_FAILED_INIT Or _
                   f_ret = BK_return.BK_FIRMWARE) Then

                    f_ret = Bikirom_NewBootloaderUpload()

                ElseIf f_ret = BK_return.BK_ATMEL_REQUIRES_REFLASH_12MHZ Or _
                f_ret = BK_return.BK_ATMEL_REQUIRES_REFLASH_16MHZ Or _
                f_ret = BK_return.BK_ATMEL_REQUIRES_REFLASH_8MHZ _
                Then
                    Dim options As New frmInformation("Firmware Update", "A Firmware update is required that will erase all BikiRom settings" & _
                                                                        "from the board (ECU data un-affected) which includes Auxiliary Ouputs," & _
                                                                        "Triggers and 0-5v lookup tables. Press 'OK' to continue with this" & _
                                                                        "update, then re-sync your Saved file via 'Bikirom -> Sync to Board'", _
                                                                        "WARNING!!! THIS WILL ERASE ALL BIKIROM SETTINGS!!!", MsgBoxStyle.OkCancel Or MsgBoxStyle.Question)

                    If options.ShowDialog = DialogResult.OK Then
                        If BikiRom_ReCodeBootloader(f_ret, nId) = BK_return.BK_OK Then
                            OnMessage("Firmware Update Re-Initialised")
                            GoTo start
                        Else
                            OnMessage("Unable to re-load firmware, Contact firmware@bikirom.com for a mnaual update")
                        End If
                    End If
                End If

            Else
                f_ret = BK_return.BK_DEVICE_NOT_FOUND
            End If

            Select Case f_ret
                Case BK_return.BK_OK
                    e.Result = MultiVersionThread.thread_result.rslt_allok
                Case BK_return.BK_FAILED_INIT, BK_return.BK_IO_ERROR_BIK
                    e.Result = MultiVersionThread.thread_result.rslt_board_fault
                Case BK_return.BK_FIRMWARE, BK_return.BK_ERROR_CATCH, BK_return.BK_BIKISOFT_REQUIRES_UPDATE, BK_return.BK_ERROR_CATCH
                    e.Result = MultiVersionThread.thread_result.rslt_bikisoft_error
                Case BK_return.BK_IO_ERROR_USB, BK_return.BK_IO_TIMEOUT
                    e.Result = MultiVersionThread.thread_result.rslt_comms_error
                Case BK_return.BK_DEVICE_NOT_FOUND
                    e.Result = MultiVersionThread.thread_result.rslt_canceled
                    OnMessage(Err_Decode(BK_return.BK_DEVICE_NOT_FOUND))
            End Select

            m_UsbCommHandler.ResetDevice()
        End Sub

        Private Function Bikirom_NewBootloaderUpload() As BK_return
            Dim f_Frame As Comm.Comm_Frame
            Dim f_Packet() As Byte = Nothing
            Dim Address As UShort = 0
            Dim Length As UShort = 0
            Dim cmd() As Byte = Nothing
            Dim f_speed As BK_return

            'BikiRom_Flush()
            m_UsbCommHandler.Timeout = 20
            'BikiRom_Reset()
            m_UsbCommHandler.ResetForBootMode()

            Threading.Thread.Sleep(100)

            Try
                f_Frame = New Comm.Comm_Frame(Comm.Comm_Frame.BikiFrameType.ID_BOOTLOADER, , , , Comm.Comm_Frame.BikiFrameType.ID_GENERAL_SPECIFIC)

                m_UsbCommHandler.SendFrame(f_Frame, f_Packet, True, 20)

                m_UsbCommHandler.Timeout = 8000

                If Not IsNothing(f_Packet) Then
                    Select Case (f_Packet(0))
                        Case &H79
                            f_speed = BK_return.BK_ATMEL_NO_REFLASH
                            m_data = cv_BytesFromHex(CryptResource(getResource(My.Settings.Firmware12_31), False).ToArray)
                        Case &H78
                            f_speed = BK_return.BK_ATMEL_NO_REFLASH
                            m_data = cv_BytesFromHex(CryptResource(getResource(My.Settings.Firmware12_33), False).ToArray)
                        Case &H75
                            f_speed = BK_return.BK_ATMEL_REQUIRES_REFLASH_16MHZ
                            m_data = cv_BytesFromHex(CryptResource(getResource(My.Settings.Firmware16), False).ToArray)
                        Case &H73
                            f_speed = BK_return.BK_ATMEL_REQUIRES_REFLASH_12MHZ
                            m_data = cv_BytesFromHex(CryptResource(getResource(My.Settings.Firmware12), False).ToArray)
                        Case &H71
                            f_speed = BK_return.BK_ATMEL_REQUIRES_REFLASH_8MHZ
                            m_data = cv_BytesFromHex(CryptResource(getResource(My.Settings.Firmware8), False).ToArray)
                        Case Else
                            OnMessage("Invalid Bootloader Response")
                            Return BK_return.BK_FAILED_INIT
                    End Select
                    OnMessage("Firmware.... Sync OK ")
                    f_Frame = New Comm.Comm_Frame(Comm.Comm_Frame.BikiFrameType.ID_LAST_COMMAND_STATUS, , , , Comm.Comm_Frame.BikiFrameType.ID_LAST_COMMAND_STATUS)
                    If m_UsbCommHandler.SendFrame(f_Frame, , True, 3) = Comm.Comm_Frame.BikiFrameResponse.CMD_OK Then
                        OnMessage("Firmware.... Updating.... ")
                        While Address < UBound(m_data)
                            Length = (m_data(Address) * &H100) + m_data(Address + 1)

                            ReDim cmd(Length - 3)
                            Array.Copy(m_data, Address + 2, cmd, 0, Length - 2)

                            f_Frame = New Comm.Comm_Frame(Comm.Comm_Frame.BikiFrameType.ID_BOOTLOADER, , , cmd, Comm.Comm_Frame.BikiFrameType.ID_LAST_COMMAND_STATUS)
                            m_UsbCommHandler.SendFrame(f_Frame, , , 4)

                            OnProgress((Address / UBound(m_data)) * 100)

                            Address += Length + 2
                        End While

                    Else
                        OnMessage("Bootloader Erasing Failed")
                        Return BK_return.BK_FIRMWARE
                    End If

                Else
                    Return BK_return.BK_FIRMWARE
                End If

                Return BK_return.BK_OK

            Catch exComm As Comm_Exceptions
                If exComm.Response = Comm.Comm_Frame.BikiFrameResponse.BOOT_FAILED Then Return f_speed
                OnMessage(exComm.Description)
                Return BK_return.BK_IO_ERROR_BIK
            Catch exUsb As USB_exceptions
                OnMessage(exUsb.Description)
                Return BK_return.BK_IO_ERROR_USB
            End Try
        End Function
        Private Function BikiRom_BootloaderUpload(ByRef ID As UInt32) As BK_return
            Dim f_packetSize As Integer = 256 'Val(txPacket.Text)
            Dim f_retBytes(0 To 20) As Byte
            Dim f_page(0 To 1) As Byte
            Dim s_error As Integer
            Dim s_crc As Integer
            Dim f_Crc As Integer
            f_Crc = f_packetSize + 1
            Dim f_returnBytes(0 To 20) As Byte
            Dim f_pageData(0 To f_packetSize + 1) As Byte
            Dim f_pageTwo(0 To f_packetSize + 1) As Byte
            Dim f_pageThree(0 To f_packetSize + 2) As Byte
            Dim f_firstByte(2) As Byte
            Dim intFirstBytes As Integer = 2
            Dim f_reflash As BK_return


            'Try
            m_UsbCommHandler.Timeout = 100
            Dim s_blEr As Integer = 0 '40
            Dim f_bytes() As Byte = Nothing
            Dim bytHeader As Byte = &HDF
            Dim f_HandshakeOk As Boolean = False

bl:
            m_UsbCommHandler.Flush()
            If s_blEr Mod 2 = 1 Then
                Me.m_UsbCommHandler.ResetForBootMode()
            Else
                Me.m_UsbCommHandler.ResetForBootModeAlternate()
            End If

            'Threading.Thread.Sleep(s_blEr * 10)

            f_bytes = usb_read(1)
            If Not IsNothing(f_bytes) AndAlso f_bytes.Length > 0 Then
                If f_bytes(0) = &HAA Then
                    Return BK_return.BK_FIRMWARE
                ElseIf f_bytes(0) <> &HBB And _
                    f_bytes(0) <> &HB1 And _
                    f_bytes(0) <> &HB9 _
                Then
                    s_blEr += 1
                    If s_blEr > 8 Then Return BK_return.BK_FIRMWARE
                    GoTo bl
                End If
            Else
                s_blEr += 1
                If s_blEr > 8 Then Return BK_return.BK_FAILED_INIT
                GoTo bl
            End If

            Select Case f_bytes(0)
                Case &HBB
                    ID = 0
                    Return BK_return.BK_ATMEL_REQUIRES_REFLASH_16MHZ
                Case &HB9
                    Dim pchId As Byte() = usb_read(3)
                    If pchId.Length > 2 Then
                        ID = CUInt(pchId(1)) << 8 + pchId(2)
                    Else
                        ID = 0
                    End If
                    Return BK_return.BK_ATMEL_REQUIRES_REFLASH_12MHZ
                Case &HB1
                    Dim pchId As Byte() = usb_read(3)
                    If pchId.Length > 2 Then
                        ID = CUInt(pchId(1)) << 8 + pchId(2)
                    Else
                        ID = 0
                    End If
                    Return BK_return.BK_ATMEL_REQUIRES_REFLASH_8MHZ
            End Select

            ' Try
            Select Case f_bytes(0)
                Case &HBB
                    f_reflash = BK_return.BK_ATMEL_REQUIRES_REFLASH_16MHZ
                    m_data = CryptResource(getResource(My.Settings.Firmware16_C), False).ToArray
                    intFirstBytes = 2
                    bytHeader = &HDF
                    f_firstByte(0) = &HDF
                    f_firstByte(1) = m_data(0)
                    f_HandshakeOk = True
                Case &HB9
                    f_reflash = BK_return.BK_ATMEL_REQUIRES_REFLASH_12MHZ
                    m_data = CryptResource(getResource(My.Settings.Firmware12_C), False).ToArray
                    'Threading.Thread.Sleep(1000)
                    usb_read(3)
                    Threading.Thread.Sleep(1000)
                    If m_UsbCommHandler.SendRawFrame("AA55AABCEFAC", "BCEFCC") Then
                        Threading.Thread.Sleep(100)
                        If m_UsbCommHandler.SendRawFrame("BCFECCAA55AA", "EFCABF") Then
                            intFirstBytes = 1
                            bytHeader = &HBF
                            f_firstByte(0) = m_data(0)
                            f_HandshakeOk = True
                            Threading.Thread.Sleep(100)
                            Exit Select
                        End If
                    End If
                    f_HandshakeOk = False
                Case &HB1
                    f_reflash = BK_return.BK_ATMEL_REQUIRES_REFLASH_8MHZ
                    m_data = CryptResource(getResource(My.Settings.Firmware8_C), False).ToArray
                    usb_read(3)
                    Threading.Thread.Sleep(1000)
                    If m_UsbCommHandler.SendRawFrame("AA55AABCEFAC", "BCEFCC") Then
                        Threading.Thread.Sleep(100)
                        If m_UsbCommHandler.SendRawFrame("BCFECCAA55AA", "EFCABF") Then
                            intFirstBytes = 1
                            bytHeader = &HBF
                            f_firstByte(0) = m_data(0)
                            f_HandshakeOk = True
                            Threading.Thread.Sleep(100)
                            Exit Select
                        End If
                    End If
                    f_HandshakeOk = False
                Case Else
                    Return BK_return.BK_BIKISOFT_REQUIRES_UPDATE
            End Select
            '  Catch
            '  Return BK_return.BK_ERROR_CATCH
            '  End Try

            f_pageData(0) = bytHeader
            f_pageTwo(0) = bytHeader
            f_pageThree(0) = bytHeader

            If m_data.Length = 0 Then
                OnMessage("Error Loading Firmware, check bikirom.com for software updates")
                Return BK_return.BK_ERROR_CATCH
            End If
            'Debug.Print("past the BB checking after wait of " & s_blEr & "ms")

            'If f_bytes(0) = 187 Then
            Threading.Thread.Sleep(100)
            OnMessage("Firmware.... Sync OK ")
            If f_HandshakeOk AndAlso m_UsbCommHandler.SendRawFrame(f_firstByte, f_retBytes, intFirstBytes, 1) Then
                If f_retBytes(0) = &HFF Then
                    f_bytes = usb_read(2)
                    If Not IsNothing(f_bytes) AndAlso _
                      (f_bytes(0) = &HEE And f_bytes(1) = &HFF) Then
                        Return f_reflash
                    End If
                End If
                If f_retBytes(0) = bytHeader Then
                    OnMessage("Firmware.... Updating.... ")
                    For i As Integer = 1 To UBound(m_data) Step (f_packetSize * 3)
                        array_copy(m_data, i, f_pageData, 1, f_packetSize)
                        array_copy(m_data, i + f_packetSize, f_pageTwo, 1, f_packetSize)
                        array_copy(m_data, i + (f_packetSize * 2), f_pageThree, 1, f_packetSize)
                        s_crc = 0
                        For d As Integer = 1 To (f_packetSize)
                            s_crc += CByte(f_pageData(d))
                        Next
                        For d As Integer = 1 To (f_packetSize)
                            s_crc += CByte(f_pageTwo(d))
                        Next
                        For d As Integer = 1 To (f_packetSize)
                            s_crc += CByte(f_pageThree(d))
                        Next
                        f_pageThree(f_packetSize + 1) = LOBYTE(s_crc)

reSend:                 If m_UsbCommHandler.SendRawFrame(f_pageData, f_retBytes, f_packetSize + 1, 1) Then
                            Debug.Print("Past 1st packet " & i)
reSend2:                    If m_UsbCommHandler.SendRawFrame(f_pageTwo, f_retBytes, f_packetSize + 1, 1) Then
                                Debug.Print("Past 2nd packet " & i)
reSend3:                        If m_UsbCommHandler.SendRawFrame(f_pageThree, f_retBytes, f_packetSize + 2, 1) = False Then
                                    OnMessage("Firmware... Updating Failed")
                                    Return BK_return.BK_FIRMWARE
                                Else
                                    Select Case f_retBytes(0)
                                        Case bytHeader
                                            s_error = 0
                                            Debug.Print(Hex(i) & " crc check ok!")
                                        Case &HDE
                                            s_error += 1
                                            If s_error >= 10 Then OnMessage("CRC ERROR # " & s_error) : Return BK_return.BK_IO_CRC_FAILED
                                            GoTo reSend
                                        Case &HEE
                                            s_error += 1
                                            If s_error >= 10 Then OnMessage("CRC ERROR # " & s_error) : Return BK_return.BK_IO_CRC_FAILED
                                            GoTo reSend3
                                    End Select
                                End If
                                ' Exit Function
                                'If (i Mod 1024) = 0 Then
                                OnProgress(((i / UBound(m_data)) * 100))
                                'End If
                            Else
                                Debug.Print("Error sending packet 2", "ERROR")
                            End If
                        Else
                            Debug.Print("Error sending packet 1", "ERROR")
                        End If
                    Next
                Else
                    GoTo bl
                    'Debug.Print("Error from initial seed byte return.. ie no return", "ERROR")
                End If
            Else
                s_blEr += 1
                If s_blEr >= 10 Then Return BK_return.BK_IO_ERROR_BIK
                GoTo bl
            End If
            Dim cmd() As Byte = cv_BytesFromHex("FF")
            If m_UsbCommHandler.SendRawFrame(cmd, f_retBytes, 1, 1) Then
                OnProgress(100)
                OnMessage("Firmware Update 100% OK")
                Return BK_return.BK_OK
            Else
                OnProgress(0)
                OnMessage("Firmware Updating Failed")
                Return BK_return.BK_FAILED_CMD
            End If

            m_UsbCommHandler.ResetForBootMode()
            'Catch ex As Exception
            'OnMessage(Err.Description)
            'End Try
        End Function
        Private Function BikiRom_ReCodeBootloader(ByVal Speed As BK_return, ByVal ID As UInt32) As BK_return
            Dim f_flash As Byte() = Nothing
            Dim f_BLoffset As Integer = 3952
            Dim f_EEoffset As Integer = 136
            Dim f_EEprom(143) As Byte
            Dim f_code(15) As Byte
            Dim rand As New Random(ID)

            Select Case Speed
                Case BK_return.BK_ATMEL_REQUIRES_REFLASH_12MHZ
                    f_flash = CryptResource(getResource("BIKIBOOT_V1.0_12.enc"), False).ToArray
                    m_UsbCommHandler.SetUsbVariable(Biki_USBvars.UV_Baud, 375)
                Case BK_return.BK_ATMEL_REQUIRES_REFLASH_16MHZ
                    f_flash = CryptResource(getResource("BIKIBOOT_V1.0_16.enc"), False).ToArray
                    m_UsbCommHandler.SetUsbVariable(Biki_USBvars.UV_Baud, 500)
                Case BK_return.BK_ATMEL_REQUIRES_REFLASH_8MHZ
                    f_flash = CryptResource(getResource("BIKIBOOT_V1.0_8.enc"), False).ToArray
                    m_UsbCommHandler.SetUsbVariable(Biki_USBvars.UV_Baud, 250)
            End Select

            If IsNothing(f_flash) Then
                OnMessage("Error Re-Initialising Bikirom, contact badbiki@bikirom.com immediatley")
                Return BK_return.BK_FIRMWARE_REQUIRES_UPDATE
            End If

            For i As Integer = 0 To 12
                f_EEprom(i) = 255
            Next
            Dim f_count As Integer = 0
            For i As Integer = 1 To 8
                rand.NextBytes(f_code)
                f_count = 0
                For Each bit As Byte In f_code
                    f_EEprom(f_EEoffset - (f_count * 8)) = bit
                    f_count += 1
                Next
                f_BLoffset += 16
                f_EEoffset += 1
            Next
            Dim s_num(2) As Byte
            rand.NextBytes(s_num)
            If ID <> 0 Then
                f_EEprom(12) = (ID >> 16UI) And &HFFUI
                f_EEprom(13) = (ID >> 8UI) And &HFFUI
                f_EEprom(14) = ID And &HFFUI
            Else
                f_EEprom(12) = s_num(0)
                f_EEprom(13) = s_num(1)
                f_EEprom(14) = s_num(2)
            End If
            f_EEprom(15) = 85

            m_UsbCommHandler.Close()

            If Not IsNothing(f_flash) AndAlso SPI_Connect() AndAlso spi_reset() Then
                chipErase()
                Threading.Thread.Sleep(10)
                SPI_out(172)
                SPI_out(164)
                SPI_in()
                SPI_out(127)
                Threading.Thread.Sleep(10)
                SPI_out(172)
                SPI_out(255)
                SPI_in()
                SPI_out(205)
                SPI_disconnect()

                m_UsbCommHandler.SetUsbVariable(Biki_USBvars.UV_BikEEPROM_CRC, 0)

                OnMessage("Firmware Pre-Initialising")

                If Not Me.setProgram(f_flash, False, True) Then OnMessage("Firmware Update Failed: Contact BadBiki Err #303") : Exit Function

                If Not Me.setEEprom(f_EEprom) Then OnMessage("Firmware Update Failed: Contact BadBiki Err #304") : Exit Function

                SPI_Connect()
                spi_reset()
                SPI_out(172)
                SPI_out(255)
                SPI_in()
                SPI_out(204)

                Threading.Thread.Sleep(10)
                SPI_disconnect()
                BikiRom_Reset()
                Close_Bikirom()

                'Dim inp As String
                'inp = InputBox("Enter the serial Number written on the back of your BikiRom USB Megaboard", "Serial Number")
                'If inp <> "" Then
                '    inp = "BikiSoftReturnFile"
                'End If
                'Dim f_eeDump As New MemoryStream(f_EEprom)
                'Dim f_eeDump2 As New MemoryStream

                'CryptFile("This IS! not a TEST moFO But This one IS", f_eeDump, f_eeDump2, True)
                'arrayDump(f_eeDump2.ToArray, Application.StartupPath & "\" & inp & ".bmd")
                'MsgBox("Inside the BikiSoft Directory:" & Chr(10) _
                '      & Application.StartupPath & Chr(10) _
                '     & "is a file named '" & inp & ".bmd" & Chr(10) _
                '     & "this needs to be emailed back to BadBiki " & Chr(10) _
                '     & "at badbiki@bikirom.com Subject:Board Update return.. cheers", MsgBoxStyle.Information, "Infomation")

                Return BK_return.BK_OK
            End If
            Close_Bikirom()
            Return Speed
        End Function
        Public Function setProgram(ByRef a_data() As Byte, ByVal AutoVerify As Boolean, ByVal Program As Boolean) As Boolean
            Dim s_return As Byte
            Dim g, adr As Long
            Dim i As Long
            Dim fnum As Integer = FreeFile()
            Dim spi_enterProgMode As Byte() = {0, rst, 0}
            Dim spi_ProgrammingEnable As Byte() = {172, 83}
            Dim spi_chipErase As Byte() = {172, 128}
            Dim m_error As Integer = 0
            Dim f_genCount As Integer
            Dim f_genCmd(24575) As Byte
            Dim f_return As Integer
            ReDim Preserve a_data(&HFFF)

            If SPI_Connect() AndAlso spi_reset() Then
                For i = 126976 To 131071 Step 256
                    If Not checkPageEmpty(a_data, i - 126976) Then
                        If Program = True Then
                            f_genCount = 0
                            For g = i To i + 255 Step 2
restartPageUpload:
                                adr = g \ 2

                                cmd_add(SPI_out_gen(64), f_genCmd, f_genCount)
                                cmd_add(SPI_out_gen(0), f_genCmd, f_genCount)

                                GoTo skip1
                                If SPI_in() <> 64 Then
                                    m_error += 1
                                    If m_error >= 100 Then
                                        Return False
                                    End If
                                    If Not spi_reset() Then Return False
                                    GoTo restartPageUpload

                                End If
skip1:
                                cmd_add(SPI_out_gen(LOBYTE(adr)), f_genCmd, f_genCount)
                                cmd_add(SPI_out_gen(a_data(g - 126976)), f_genCmd, f_genCount)

                                cmd_add(SPI_out_gen(72), f_genCmd, f_genCount)
                                cmd_add(SPI_out_gen(0), f_genCmd, f_genCount)
                                GoTo skip2
                                If SPI_in() <> 72 Then
                                    m_error += 1
                                    If m_error >= 100 Then
                                        Return False
                                    End If
                                    If Not spi_reset() Then Return False
                                    GoTo restartPageUpload

                                End If
skip2:
                                cmd_add(SPI_out_gen(LOBYTE(adr)), f_genCmd, f_genCount)
                                cmd_add(SPI_out_gen(a_data(g + 1 - 126976)), f_genCmd, f_genCount)
                            Next

                            FT_Write_Bytes(lngHandle, f_genCmd(0), 24575, f_return)

                            SPI_out(76)
                            SPI_out(HIBYTE(adr))
                            SPI_out(LOBYTE(adr))
                            s_return = SPI_in()
                            If LOBYTE(adr) <> s_return Then Debug.Print("Potenialy Failing on the Page Write command")
                            Debug.Print(s_return)
                            Threading.Thread.Sleep(20)
                        End If

                        OnProgress(((i - 126976) / 4096) * 100)
                    End If
                Next
                Return True
            Else
                Return False
            End If
            OnProgress(100)
            SPI_disconnect()
            Exit Function
        End Function
        Private Sub cmd_add(ByRef f_from() As Byte, ByRef f_array() As Byte, ByRef f_count As Integer)
            array_copy(f_from, 0, f_array, f_count, f_from.Length)
            f_count += f_from.Length
        End Sub
        Public Function setEEprom(ByRef s_data() As Byte) As Boolean
            Dim i As Long
            Dim fnum As Integer = FreeFile()
            Dim spi_enterProgMode As Byte() = {0, rst, 0}
            Dim spi_ProgrammingEnable As Byte() = {172, 83}
            Dim f_sndCmd(95) As Byte
            Dim f_cmdCount As Integer
            Dim f_written As Integer

            If Not IsNothing(s_data) AndAlso SPI_Connect() AndAlso spi_reset() Then
                For i = 0 To 143
                    If s_data(i) <> 255 Then
                        f_cmdCount = 0
                        cmd_add(SPI_out_gen(192), f_sndCmd, f_cmdCount)
                        cmd_add(SPI_out_gen(HIBYTE(i)), f_sndCmd, f_cmdCount)
                        cmd_add(SPI_out_gen(LOBYTE(i)), f_sndCmd, f_cmdCount)
                        cmd_add(SPI_out_gen(s_data(i)), f_sndCmd, f_cmdCount)

                        FT_Write_Bytes(lngHandle, f_sndCmd(0), 96, f_written)
                        Threading.Thread.Sleep(40)
                    End If
                    OnProgress((i / 143) * 100)
                Next
                Return True
            Else
                Return False
            End If
            SPI_disconnect()
        End Function

    End Class
End Namespace

